﻿using System;
using UnityEngine;

namespace PlaygroundSplines
{
	// Token: 0x0200014E RID: 334
	[ExecuteInEditMode]
	public class PlaygroundSplineMesh : MonoBehaviour
	{
		// Token: 0x0600072F RID: 1839 RVA: 0x0002A874 File Offset: 0x00028A74
		public virtual void OnEnable()
		{
			if (this.noiseDistributionL == null || this.noiseDistributionL.keys.Length == 0)
			{
				this.SetAnimationCurveVals(ref this.noiseDistributionL);
			}
			if (this.noiseDistributionR == null || this.noiseDistributionR.keys.Length == 0)
			{
				this.SetAnimationCurveVals(ref this.noiseDistributionR);
			}
			if (base.GetComponent<Renderer>() == null)
			{
				base.gameObject.AddComponent<MeshRenderer>();
			}
			if (this.spline == null)
			{
				this.spline = base.GetComponent<PlaygroundSpline>();
			}
			if (this.spline != null)
			{
				this.BuildSplineMesh(this.spline, this.points, this.width);
			}
			this.SetVals();
		}

		// Token: 0x06000730 RID: 1840 RVA: 0x0002A93C File Offset: 0x00028B3C
		public virtual void Update()
		{
			if (this.NeedsUpdate())
			{
				if (this.spline != null)
				{
					this.BuildSplineMesh(this.spline, this.points, this.width);
				}
				this.SetVals();
			}
		}

		// Token: 0x06000731 RID: 1841 RVA: 0x0002A978 File Offset: 0x00028B78
		public virtual bool NeedsUpdate()
		{
			return this.prevPoints != this.points || this.prevWidth != this.width || this.prevNoise != this.noise || (this.noise && (this.prevNoiseScale != this.noiseScale || this.prevNoiseStrength != this.noiseStrength || this.prevNoiseDistribution != this.noiseDistribution)) || this.prevFollowSurface != this.followSurface || this.prevFollowSurfaceRotation != this.followSurfaceRotation || this.prevSurfaceOffset != this.surfaceOffset || this.prevMeshUpDirection != this.meshUpDirection || this.prevSurfaceDirection != this.surfaceDirection;
		}

		// Token: 0x06000732 RID: 1842 RVA: 0x0002AA58 File Offset: 0x00028C58
		public virtual void SetVals()
		{
			this.prevPoints = this.points;
			this.prevWidth = this.width;
			this.prevNoise = this.noise;
			this.prevNoiseStrength = this.noiseStrength;
			this.prevNoiseScale = this.noiseScale;
			this.prevNoiseDistribution = this.noiseDistribution;
			this.prevFollowSurface = this.followSurface;
			this.prevFollowSurfaceRotation = this.followSurfaceRotation;
			this.prevSurfaceOffset = this.surfaceOffset;
			this.prevMeshUpDirection = this.meshUpDirection;
			this.prevSurfaceDirection = this.surfaceDirection;
		}

		// Token: 0x06000733 RID: 1843 RVA: 0x0002AAEC File Offset: 0x00028CEC
		public virtual void SetAnimationCurveVals(ref AnimationCurve curve)
		{
			Keyframe[] array = new Keyframe[2];
			array[0].time = 0f;
			array[1].time = 1f;
			array[0].value = 1f;
			array[1].value = 1f;
			curve.keys = array;
		}

		// Token: 0x06000734 RID: 1844 RVA: 0x0002AB4C File Offset: 0x00028D4C
		public virtual void BuildSplineMesh(PlaygroundSpline spline, int points, float width)
		{
			if (points < 2)
			{
				points = 2;
			}
			int num = points * 2;
			MeshFilter meshFilter = (!(base.GetComponent<MeshFilter>() != null)) ? base.gameObject.AddComponent<MeshFilter>() : base.GetComponent<MeshFilter>();
			Mesh mesh = new Mesh();
			Vector3[] array = new Vector3[num];
			Vector2[] array2 = new Vector2[num];
			int[] array3 = new int[(points - 1) * 6];
			Vector3 normal = this.meshUpDirection;
			for (int i = 0; i < points; i++)
			{
				float num2 = (float)i * 1f / (float)(points - 1);
				float num3 = ((float)i * 1f + 1f) / (float)(points - 1);
				if (num2 >= 1f && !spline.Loop)
				{
					num2 = 0.9999f;
				}
				if (num3 >= 1f && !spline.Loop)
				{
					num3 = 0.99999f;
				}
				Vector3 vector = spline.GetPoint(num2);
				Vector3 vector2 = spline.GetPoint(num3);
				if (this.followSurface || this.followSurfaceRotation)
				{
					RaycastHit raycastHit;
					if (Physics.Raycast(vector, this.surfaceDirection, out raycastHit))
					{
						if (this.followSurfaceRotation)
						{
							normal = raycastHit.normal;
						}
						if (this.followSurface)
						{
							vector = raycastHit.point + raycastHit.normal * this.surfaceOffset;
						}
					}
					if (this.followSurface && Physics.Raycast(vector2, this.surfaceDirection, out raycastHit))
					{
						vector2 = raycastHit.point + raycastHit.normal * this.surfaceOffset;
					}
				}
				float num4 = (!this.noise) ? 0f : (Mathf.PerlinNoise(num2 % 1f * this.noiseScale.x, 0f) * this.noiseStrength);
				float num5 = (!this.noise) ? 0f : (Mathf.PerlinNoise(num2 % 1f * this.noiseScale.y, 0f) * this.noiseStrength);
				if (this.noise && this.noiseDistribution)
				{
					num4 *= this.noiseDistributionL.Evaluate(num2);
					num5 *= this.noiseDistributionR.Evaluate(num2);
				}
				Vector3 normalized = Vector3.Cross(normal, vector2 - vector).normalized;
				Vector3 vector3 = vector + normalized * (width / 2f + num4);
				Vector3 vector4 = vector - normalized * (width / 2f + num5);
				array[i * 2] = vector3;
				array[i * 2 + 1] = vector4;
				array2[i * 2] = new Vector2(num2, 0f);
				array2[i * 2 + 1] = new Vector2(num2, 1f);
				if (i > 0)
				{
					int num6 = (i - 1) * 6;
					int num7 = i * 2;
					array3[num6] = num7 - 2;
					array3[num6 + 1] = num7 - 1;
					array3[num6 + 2] = num7;
					array3[num6 + 3] = num7;
					array3[num6 + 4] = num7 - 1;
					array3[num6 + 5] = num7 + 1;
				}
			}
			mesh.vertices = array;
			mesh.uv = array2;
			mesh.triangles = array3;
			mesh.RecalculateNormals();
			meshFilter.mesh = mesh;
		}

		// Token: 0x04000731 RID: 1841
		public PlaygroundSpline spline;

		// Token: 0x04000732 RID: 1842
		[Range(2f, 1000f)]
		public int points = 100;

		// Token: 0x04000733 RID: 1843
		[Range(0.01f, 100f)]
		public float width = 1f;

		// Token: 0x04000734 RID: 1844
		public bool noise;

		// Token: 0x04000735 RID: 1845
		[Range(0.01f, 100f)]
		public float noiseStrength = 1f;

		// Token: 0x04000736 RID: 1846
		public Vector2 noiseScale = new Vector2(1f, 1f);

		// Token: 0x04000737 RID: 1847
		public bool noiseDistribution;

		// Token: 0x04000738 RID: 1848
		public AnimationCurve noiseDistributionL;

		// Token: 0x04000739 RID: 1849
		public AnimationCurve noiseDistributionR;

		// Token: 0x0400073A RID: 1850
		public bool followSurface;

		// Token: 0x0400073B RID: 1851
		public bool followSurfaceRotation;

		// Token: 0x0400073C RID: 1852
		public float surfaceOffset = 0.1f;

		// Token: 0x0400073D RID: 1853
		public Vector3 meshUpDirection = Vector3.up;

		// Token: 0x0400073E RID: 1854
		public Vector3 surfaceDirection = Vector3.down;

		// Token: 0x0400073F RID: 1855
		protected int prevPoints;

		// Token: 0x04000740 RID: 1856
		protected float prevWidth;

		// Token: 0x04000741 RID: 1857
		protected bool prevNoise;

		// Token: 0x04000742 RID: 1858
		protected float prevNoiseStrength;

		// Token: 0x04000743 RID: 1859
		protected Vector2 prevNoiseScale;

		// Token: 0x04000744 RID: 1860
		protected bool prevNoiseDistribution;

		// Token: 0x04000745 RID: 1861
		protected bool prevFollowSurface;

		// Token: 0x04000746 RID: 1862
		protected bool prevFollowSurfaceRotation;

		// Token: 0x04000747 RID: 1863
		protected float prevSurfaceOffset;

		// Token: 0x04000748 RID: 1864
		protected Vector3 prevMeshUpDirection;

		// Token: 0x04000749 RID: 1865
		protected Vector3 prevSurfaceDirection;
	}
}
